package com.zhwei.gulimall.order.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class MyRabbitConfig {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 使用json序列化机制，进行消息转换
     * @return
     */
    @Bean
    public MessageConverter messageConverter(){

        return new Jackson2JsonMessageConverter();
    }

    /**
     * 为了演示这个消息确保机制，我们来定制RabbitTemplate
     * PostConstruct:表示这个类MyRabbitConfig构造好了之后会调用这个方法。
     * 1. 配置文件中开启消息确认机制
     * 2. 设置确认回调
     */
    @PostConstruct
    public void initRabbitTemplate(){
        //设置消息确认
        rabbitTemplate.setConfirmCallback(
                new RabbitTemplate.ConfirmCallback() {
                    /**
                     * 只要消息能到达服务器exchage,就是返回true
                     * @param correlationData 当前消息的唯一关联数据，唯一id
                     * @param b  消息是否成功收到
                     * @param s  消息失败原因
                     */
                    @Override
                    public void confirm(CorrelationData correlationData, boolean b, String s) {
                        System.out.println("correlationData===="+correlationData+"====ack=="+b+", 原因case:"+s);
                    }
                }
        );
        // 设置消息抵达队列的确认回调
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             * 只要消息没有投递给指定的队列，就触发这个失败回调
             * @param message 投递失败的消息的详细信息
             * @param i  恢复的状态吗
             * @param s  回复的文本内容
             * @param s1 当时这个消息发给哪个交换器
             * @param s2 当时这个消息用哪个路由键
             */
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                System.out.println("发送失败的消息消息内容我暂时省略:, 回复的状态码："+i+",回复的文本内容"+s1+", 路由键:"+s2);
            }
        });
    }
}
